package com.sf.fy.uav.applet.config;

import com.sf.fy.uav.applet.banner.controller.SysBannerController;
import com.sf.fy.uav.applet.controller.operate.SysCouponActivityController;
import com.sf.fy.uav.applet.controller.operate.SysNoticeController;
import com.sf.fy.uav.common.enums.SettingStatusEnum;
import com.sf.fy.uav.common.enums.ServicePrefixEnum;
import com.sf.fy.uav.common.request.common.IdRequest;
import com.sf.fy.uav.common.response.operational.SysBannerResponse;
import com.sf.fy.uav.common.response.operational.SysNoticeResponse;
import com.sf.fy.uav.common.utils.RedisPrefixKey;
import com.sf.fy.uav.common.utils.Rs;
import com.sf.fy.uav.entity.Coupon;
import com.sf.fy.uav.entity.CouponActivity;
import com.sf.fy.uav.mapper.CouponActivityMapper;
import com.sf.fy.uav.mapper.CouponMapper;
import com.sf.fy.uav.order.entity.OrderInfo;
import com.sf.fy.uav.order.mapper.OrderInfoMapper;
import com.sf.fy.uav.rest.CouponRest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Set;

/**
 * @author LTQ
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DelayQueue {
    //相当于队列的键
    public static final String DELAY_MESSAGE_QUEUE = "delayQueue";

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private final RedisTemplate<String, String> redisTemplate;

    @Autowired
    private SysBannerController sysBannerController;

    @Autowired
    private SysCouponActivityController sysCouponActivityController;

    @Autowired
    private CouponActivityMapper couponActivityMapper;


    @Autowired
    private SysNoticeController sysNoticeController;


    @Autowired
    private CouponMapper couponMapper;


    @Autowired
    private DelayQueue delayQueue;

    @Autowired
    private MySocket mySocket;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private CouponRest couponRest;


    /**
     * 消息入队
     * 只要用户继续发起请求，就会继续延长时间戳的时间 直到用户一直没有请求后，然后到达指定时间给消费者进行消费
     * 如果有其他用户进来，那么这个队列会根据时间戳进行排序 排在前面的并且达到指定时间就先进行消费
     *
     * @param msg
     * @param time
     */
    public void pushQueue(String msg, Long time) {
        try {
            // 存的值是集合的主键 一般固定
            // 第二个是id 每个用户一个id
            // 第三个是根据什么进行排序，这里是根据时间戳，这里如果是同个key，那么会刷新同个key的时间戳并重新进行排序
            // 不同的key就是当前时间加10秒，也就是10秒后过期
            redisTemplate.opsForZSet().add(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, msg, System.currentTimeMillis() + time);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 消息出队
     * 权重就是时间戳
     */
    @Scheduled(cron = "0/1 * * * * ?")
    public void pullQueue() {
        System.out.println("------------等待消费--------------" + simpleDateFormat.format(System.currentTimeMillis()));
        // 获取0-当前时间戳的范围的所有值
        Set<String> set = redisTemplate.opsForZSet().rangeByScore(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, 0, System.currentTimeMillis());
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            String value = iterator.next();
            if (value.startsWith(ServicePrefixEnum.EXPRESS_SYSTEM.name())) {
                // 遍历取出每一个score
                Double score = redisTemplate.opsForZSet().score(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                if (!ObjectUtils.isEmpty(score)) {

                    // 达到时间进行消费 当前时间大于
                    if (System.currentTimeMillis() > score) {
                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.BANNER_UP_COUNT_DOWN)) {
                            String bannerId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.BANNER_UP_COUNT_DOWN, "");
                            IdRequest idRequest = new IdRequest();
                            idRequest.setId(bannerId);
                            Rs<Integer> rs = sysBannerController.start(idRequest);
                            Integer status = rs.getData();
                            if (!ObjectUtils.isEmpty(status)) {
                                if (status.equals(SettingStatusEnum.ON_DISPLAY.getStatus()) || status.equals(SettingStatusEnum.ENDED.getStatus())) {
                                    // 移除该队列的值
                                    redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                                    log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                                    Rs<SysBannerResponse> bannerResponseRs = sysBannerController.getById(bannerId);
                                    SysBannerResponse bannerResponse = bannerResponseRs.getData();
                                    delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.BANNER_DOWN_COUNT_DOWN + bannerResponse.getId(), bannerResponse.getEndTime().getTime() - System.currentTimeMillis());
                                }
                            }
                        }

                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_ACTIVITY_UP_COUNT_DOWN)) {
                            String couponActivityId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_ACTIVITY_UP_COUNT_DOWN, "");
                            IdRequest idRequest = new IdRequest();
                            idRequest.setId(couponActivityId);
                            Rs<Integer> rs = sysCouponActivityController.start(idRequest);
                            Integer status = rs.getData();
                            if (!ObjectUtils.isEmpty(status)) {
                                if (status.equals(SettingStatusEnum.ON_DISPLAY.getStatus()) || status.equals(SettingStatusEnum.ENDED.getStatus())) {
                                    // 移除该队列的值
                                    redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                                    log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                                    CouponActivity couponActivity = couponActivityMapper.selectById(couponActivityId);
                                    delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.BANNER_DOWN_COUNT_DOWN + couponActivity.getId(), couponActivity.getEndActivityTime().getTime() - System.currentTimeMillis());
                                }
                            }
                        }

                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.NOTICE_UP_COUNT_DOWN)) {
                            String noticeId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.NOTICE_UP_COUNT_DOWN, "");
                            IdRequest idRequest = new IdRequest();
                            idRequest.setId(noticeId);
                            Rs<Integer> rs = sysNoticeController.start(idRequest);
                            Integer status = rs.getData();
                            if (!ObjectUtils.isEmpty(status)) {
                                if (status.equals(SettingStatusEnum.ON_DISPLAY.getStatus()) || status.equals(SettingStatusEnum.ENDED.getStatus())) {
                                    // 移除该队列的值
                                    redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                                    log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                                    Rs<SysNoticeResponse> sysNoticeResponseRs = sysNoticeController.getById(noticeId);
                                    SysNoticeResponse sysNoticeResponse = sysNoticeResponseRs.getData();
                                    delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.NOTICE_DOWN_COUNT_DOWN + sysNoticeResponse.getId(), sysNoticeResponse.getEndTime().getTime() - System.currentTimeMillis());
                                }
                            }
                        }


                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_UP_COUNT_DOWN)) {
                            String couponId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_UP_COUNT_DOWN, "");
                            IdRequest idRequest = new IdRequest();
                            idRequest.setId(couponId);
                            Integer status = couponRest.start(idRequest);
                            if (!ObjectUtils.isEmpty(status)) {
                                if (status.equals(SettingStatusEnum.ON_DISPLAY.getStatus()) || status.equals(SettingStatusEnum.ENDED.getStatus())) {
                                    // 移除该队列的值
                                    redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                                    log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                                    Coupon coupon = couponMapper.selectById(couponId);
                                    delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_DOWN_COUNT_DOWN + coupon.getId(), coupon.getFailureTime().getTime() - System.currentTimeMillis());
                                }
                            }
                        }


                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_DOWN_COUNT_DOWN)) {
                            String couponId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_DOWN_COUNT_DOWN, "");
                            IdRequest idRequest = new IdRequest();
                            idRequest.setId(couponId);
                            Integer status = couponRest.end(idRequest);
                            if (!ObjectUtils.isEmpty(status) && status.equals(SettingStatusEnum.ENDED.getStatus())) {
                                // 移除该队列的值
                                redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                                log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                            }
                        }


                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_ACTIVITY_DOWN_COUNT_DOWN)) {
                            String orderId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_ACTIVITY_DOWN_COUNT_DOWN, "");
                            IdRequest idRequest = new IdRequest();
                            idRequest.setId(orderId);
                            Rs<Integer> rs = sysCouponActivityController.end(idRequest);
                            Integer status = rs.getData();
                            if (!ObjectUtils.isEmpty(status) && status.equals(SettingStatusEnum.ENDED.getStatus())) {
                                // 移除该队列的值
                                redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                                log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                            }
                        }


                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.BANNER_DOWN_COUNT_DOWN)) {
                            String orderId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.BANNER_DOWN_COUNT_DOWN, "");
                            IdRequest idRequest = new IdRequest();
                            idRequest.setId(orderId);
                            Rs<Integer> rs = sysBannerController.end(idRequest);
                            Integer status = rs.getData();
                            if (!ObjectUtils.isEmpty(status) && status.equals(SettingStatusEnum.ENDED.getStatus())) {
                                // 移除该队列的值
                                redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                                log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                            }
                        }


                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.NOTICE_DOWN_COUNT_DOWN)) {
                            String orderId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.NOTICE_DOWN_COUNT_DOWN, "");
                            IdRequest idRequest = new IdRequest();
                            idRequest.setId(orderId);
                            Rs<Integer> rs = sysNoticeController.end(idRequest);
                            Integer status = rs.getData();
                            if (!ObjectUtils.isEmpty(status) && status.equals(SettingStatusEnum.ENDED.getStatus())) {
                                // 移除该队列的值
                                redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                                log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                            }
                        }

                        if (value.contains(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.SOCKET_TOKEN)) {
                            String orderId = value.replace(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.SOCKET_TOKEN, "");
                            OrderInfo orderinfo = orderInfoMapper.selectById(orderId);
                            if (!ObjectUtils.isEmpty(orderinfo)) {
                                mySocket.onMessageToWebAdminer("新接到订单:" + orderinfo.getTcWaybillNo() + "，请及时处理");
                            }
                            // 移除该队列的值
                            redisTemplate.opsForZSet().remove(ServicePrefixEnum.EXPRESS_SYSTEM + "." + DELAY_MESSAGE_QUEUE, value);
                            log.info("消费了" + value + "消费时间 " + simpleDateFormat.format(System.currentTimeMillis()));
                        }
                    }
                }
            }

        }
    }

}

